﻿/*
 *  Copyright 2009 Coditate Software
 *  Licensed under the GNU Library General Public License (LGPL) 2.1 
 *  
 *  License available at: http://simplesavant.codeplex.com/license
 */
using System;

namespace Coditate.Savant.Async
{
    /// <summary>
    /// Tracks the status of an asynchronous call to Savant via extension methods (<see cref="AsyncExtensions"/>).
    /// </summary>
    /// <typeparam name="R">The function return type</typeparam>
    /// <remarks>
    /// This class tracks the results of asynchronous functions. These "functions" are used
    /// with any methods that returns a value.
    /// </remarks>
    public class AsyncFunction<R> : AsyncOperation
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="AsyncFunction{R}"/> class.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="savant">The savant instance.</param>
        internal AsyncFunction(Func<ISimpleSavant, R> function, ISimpleSavant savant)
            : base(savant)
        {
            Function = function;
        }

        /// <summary>
        /// Gets or sets the function to invoke.
        /// </summary>
        /// <value>The function.</value>
        internal Func<ISimpleSavant, R> Function { get; private set; }

        /// <summary>
        /// Ends the asynchronous invocation.
        /// </summary>
        /// <returns>The value returned from SimpleDB</returns>
        /// <remarks>
        /// This method blocks until the function completes. If the function invocation
        /// threw an exception it is rethrown here.
        /// </remarks>
        public R EndInvoke()
        {
            R returnValue = Function.EndInvoke(Result);

            return returnValue;
        }

        internal void BeginInvoke()
        {
            Result = Function.BeginInvoke(Savant, null, null);
        }
    }
}